<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>记事本</title>
    <script src="/js/vue/vue.js"></script>
    <script src="/js/vue/axios.js"></script>
    <script src="/js/vue/element-ui.js"></script>
    <style>
        @import url("/css/vue/element-ui.css");
        .el-message {
            min-width: 100px !important;
            max-width: 80% !important;
        }

        :root {
            --primary-color: #4361ee;
            --bg-color: #f5f7fa;
            --text-color: #303133;
            --border-color: #dcdfe6;
        }

        body {
            margin: 0;
            padding: 0;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
            background-color: var(--bg-color);
            color: var(--text-color);
            -webkit-tap-highlight-color: transparent;
        }

        #app {
            max-width: 100vw;
            overflow-x: hidden;
        }

        .mobile-header {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            height: 50px;
            background-color: var(--primary-color);
            color: white;
            display: flex;
            align-items: center;
            padding: 0 15px;
            z-index: 1000;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        }

        .header-title {
            flex: 1;
            text-align: center;
            font-size: 18px;
            font-weight: bold;
        }

        .header-menu {
            font-size: 24px;
        }

        .main-container {
            margin-top: 50px;
            padding-bottom: 60px;
        }

        .tree-container {
            padding: 10px;
        }

        .mobile-tree-node {
            display: flex;
            align-items: center;
            padding: 12px 15px;
            border-bottom: 1px solid #eee;
        }

        .tree-icon {
            margin-right: 10px;
            font-size: 18px;
        }

        .tree-title {
            flex: 1;
            font-size: 16px;
        }

        .tree-actions {
            display: flex;
        }

        .folder-toggle {
            margin-right: 8px;
            width: 20px;
            text-align: center;
        }

        .editor-container {
            padding: 15px;
        }

        .editor-toolbar {
            display: flex;
            margin-bottom: 10px;
            flex-wrap: wrap;
        }

        .editor-toolbar .el-select {
            margin-right: 8px;
            margin-bottom: 8px;
        }

        .editor-textarea {
            width: 95%;
            min-height: 750px;
            padding: 10px;
            border-radius: 4px;
            font-family: "Consolas", monospace;
            font-size: 16px;
            line-height: 1.5;
            resize: none;
            color: darkslategray;
            /*white-space: nowrap;*/
            /*overflow-x: auto;*/
            border: 1px solid var(--border-color);
        }

        .output-title {
            margin: 15px 0 8px 0;
            font-weight: bold;
        }

        .action-buttons {
            position: fixed;
            bottom: 0;
            left: 0;
            right: 0;
            display: flex;
            background-color: white;
            padding: 10px;
            box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
            z-index: 999;
        }

        .action-buttons .el-button {
            flex: 1;
            margin: 0 5px;
        }

        .folder-drawer .el-drawer__body {
            padding: 20px;
        }

        .folder-form .el-form-item {
            margin-bottom: 20px;
        }

        .menu-drawer .el-drawer__body {
            padding: 0;
        }

        .menu-item {
            padding: 15px;
            border-bottom: 1px solid #eee;
            display: flex;
            align-items: center;
            width: 210px;
        }

        .menu-item-icon {
            margin-right: 10px;
            font-size: 20px;
        }

        /* 页面切换动画 */
        .page-enter-active, .page-leave-active {
            transition: transform 0.3s ease;
        }
        .page-enter {
            transform: translateX(100%);
        }
        .page-leave-to {
            transform: translateX(-100%);
        }

        @media (prefers-color-scheme: dark) {
            :root {
                --primary-color: #4361ee;
                --bg-color: #121212;
                --text-color: #e0e0e0;
                --border-color: #333;
            }

            body {
                background-color: var(--bg-color);
                color: var(--text-color);
            }

            .mobile-tree-node {
                border-bottom-color: #333;
            }

            .editor-textarea {
                background-color: #1e1e1e;
                color: #e0e0e0;
                border-color: #333;
            }

            .action-buttons {
                background-color: #1e1e1e;
            }

            .menu-item {
                border-bottom-color: #333;
            }
        }
    </style>
</head>
<body>
<div id="app">
    <!-- 移动端顶部栏 -->
    <div class="mobile-header">
        <div class="header-menu" @click="drawerVisible = true">
            <i class="el-icon-menu"></i>
        </div>
        <div class="header-title">{{ currentTitle }}</div>
    </div>

    <!-- 主内容区 -->
    <div class="main-container">
        <!-- 树形结构 -->
        <transition name="page" mode="out-in">
            <div class="tree-container" v-show="!showEditor" :key="'list'">
                <div v-for="node in visibleTreeData"
                     :key="node.id"
                     :style="{paddingLeft: (node.level * 15) + 'px'}"
                     class="mobile-tree-node"
                     @click="handleNodeClick(node)">
                    <span class="folder-toggle" v-if="node.type === 0 && node.children && node.children.length">
                        <i class="el-icon-arrow-right" v-if="!expandedKeys.includes(node.id)"></i>
                        <i class="el-icon-arrow-down" v-else></i>
                    </span>
                    <span class="folder-toggle" v-else></span>
                    <span class="tree-icon">
                        <template v-if="node.id === -1">🚥</template>
                        <template v-else-if="node.id === 0">📌</template>
                        <template v-else-if="node.id === -99">♻️</template>
                        <template v-else-if="node.type >= 0">{{node.icon}}</template>
                    </span>
                    <span class="tree-title">{{ node.title }}</span>
                    <span class="tree-actions" v-if="node.id > 0" @click.stop>
                        <i class="el-icon-edit" @click="openFolderDrawer(node)" v-if="node.type === 0"></i>
                        <i class="el-icon-delete" @click="deleteMemo(node)" style="margin-left: 10px;"></i>
                    </span>
                </div>
            </div>
        </transition>

        <!-- 编辑器 -->
        <transition name="page" mode="out-in">
            <div class="editor-container" v-show="showEditor" :key="'editor'">
                <div class="editor-toolbar">
                    <el-select v-model="currentMemo.parentId" size="small" placeholder="选择文件夹">
                        <el-option v-for="item in folderData"
                                   :key="item.id"
                                   :label="item.title"
                                   :value="item.id"></el-option>
                    </el-select>
                    <el-input v-model="currentMemo.title" size="small" placeholder="标题" style="flex: 1;"></el-input>
                </div>
                <textarea class="editor-textarea" v-model="currentMemo.context" placeholder="输入内容..."></textarea>
                <div class="output-title" v-if="showCodeEditor">输出</div>
                <textarea class="editor-textarea" v-model="output" readonly v-if="showCodeEditor"></textarea>
            </div>
        </transition>
    </div>

    <!-- 底部操作按钮 -->
    <div class="action-buttons" v-show="showEditor">
        <el-button size="small" @click="goBack">返回</el-button>
        <el-button size="small" type="primary" @click="saveMemo">保存</el-button>
        <el-button size="small" type="success" @click="run" v-if="showCodeEditor">运行</el-button>
    </div>

    <!-- 文件夹编辑抽屉 -->
    <el-drawer title="编辑文件夹" :visible.sync="folderDrawer" size="80%" class="folder-drawer">
        <div class="folder-form">
            <el-form label-width="80px">
                <el-form-item label="名称">
                    <el-input v-model="currentFolder.title" placeholder="文件夹名称"></el-input>
                </el-form-item>
                <el-form-item label="排序">
                    <el-input-number v-model="currentFolder.sort" :min="0"></el-input-number>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="saveFolder">保存</el-button>
                </el-form-item>
            </el-form>
        </div>
    </el-drawer>

    <!-- 菜单抽屉 -->
    <el-drawer title="菜单" :visible.sync="drawerVisible" direction="right" size="100%" class="menu-drawer">
        <div class="menu-item" @click="jump('/')">
            <span class="menu-item-icon">🍡</span>
            <span>导航主页</span>
        </div>
        <div class="menu-item" @click="jump('/memo')">
            <span class="menu-item-icon">📌</span>
            <span>记事本</span>
        </div>
        <div class="menu-item" @click="jump('/cash')">
            <span class="menu-item-icon">💰</span>
            <span>记账本</span>
        </div>
        <div class="menu-item" @click="jump('/page')">
            <span class="menu-item-icon">🌈</span>
            <span>动态页面</span>
        </div>
        <div class="menu-item" @click="jump('/task')">
            <span class="menu-item-icon">⏱️</span>
            <span>定时任务</span>
        </div>
        <div class="menu-item" @click="jump('/setting')">
            <span class="menu-item-icon">⚙️</span>
            <span>个人设置</span>
        </div>
        <div class="menu-item" @click="jump('/readme')">
            <span class="menu-item-icon">📖</span>
            <span>帮助手册</span>
        </div>
        <div class="menu-item" @click="jump('/doc.html')">
            <span class="menu-item-icon">🛠️</span>
            <span>接口文档</span>
        </div>
    </el-drawer>
</div>

<script>
    var Main = {
        data() {
            return {
                drawerVisible: false,
                folderDrawer: false,
                showEditor: false,
                showCodeEditor: false,
                currentTitle: '记事本',
                treeData: [],
                flatTreeData: [],
                folderData: [],
                output: '',
                currentMemo: {
                    id: null,
                    parentId: null,
                    sort: 0,
                    type: 1,
                    title: '',
                    context: '',
                },
                currentFolder: {
                    id: null,
                    parentId: null,
                    sort: 0,
                    type: 0,
                    title: '',
                    context: '',
                },
                expandedKeys: [0],
                // 添加页面历史记录
                pageHistory: []
            }
        },
        computed: {
            visibleTreeData() {
                const result = [];
                const stack = [...this.treeData];

                while (stack.length) {
                    const node = stack.shift();

                    // 如果节点是文件夹且未展开，则跳过其子节点
                    const isExpanded = this.expandedKeys.includes(node.id);
                    const shouldSkipChildren = node.type === 0 && !isExpanded;

                    // 添加当前节点到结果
                    result.push(node);

                    // 如果不需要跳过子节点且有子节点，则将子节点添加到栈的开头
                    if (!shouldSkipChildren && node.children && node.children.length) {
                        stack.unshift(...node.children);
                    }
                }

                return result;
            }
        },
        mounted() {
            this.checkToken();
            // 初始化历史记录
            this.pageHistory.push('list');

            // 监听浏览器后退按钮
            window.addEventListener('popstate', this.handlePopState);
        },
        beforeDestroy() {
            window.removeEventListener('popstate', this.handlePopState);
        },
        methods: {
            handlePopState(event) {
                // 当用户点击浏览器后退按钮时触发
                if (this.pageHistory.length > 1) {
                    this.pageHistory.pop();
                    const previousPage = this.pageHistory[this.pageHistory.length - 1];

                    if (previousPage === 'list') {
                        this.showEditor = false;
                        this.currentTitle = '记事本';
                    }
                }
            },
            goBack() {
                // 返回按钮点击处理
                if (this.pageHistory.length > 1) {
                    this.pageHistory.pop();
                    this.showEditor = false;
                    this.currentTitle = '记事本';

                    // 添加历史记录，确保浏览器后退按钮也能工作
                    if (window.history && window.history.pushState) {
                        window.history.back();
                    }
                }
            },
            navigateToEditor() {
                // 导航到编辑器
                this.pageHistory.push('editor');
                this.showEditor = true;

                // 添加历史记录
                if (window.history && window.history.pushState) {
                    window.history.pushState({ page: 'editor' }, '', '');
                }
            },
            checkToken() {
                localStorage.setItem('jump', window.location.href);
                axios.get('/login/checkToken', {
                    params: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    if(!response.data.data) {
                        this.localStorage.setItem('token', '');
                        window.location.href = '/login';
                        return;
                    }
                    this.getTree();
                    this.getFolder();
                });
            },
            getTree() {
                axios.get('/memo/getTree', {
                    headers: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    this.treeData = response.data.data.slice(1);
                    this.flattenTree(this.treeData);
                    // 默认展开根文件夹
                    // if (this.treeData.length > 0) {
                    //     this.expandedKeys = [this.treeData[0].id];
                    // }
                }).catch((error) => {
                    this.$message.error(error.message);
                });
            },
            flattenTree(tree, level = 0, result = []) {
                tree.forEach(node => {
                    node.level = level;
                    result.push(node);
                    if (node.children && node.children.length > 0) {
                        this.flattenTree(node.children, level + 1, result);
                    }
                    if (node.isExpand === 1) {
                        this.expandedKeys.push(node.id);
                    }
                });
                this.flatTreeData = result;
            },
            getFolder() {
                axios.get('/memo/getFolder', {
                    headers: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    this.folderData = response.data.data;
                }).catch((error) => {
                    this.$message.error(error.message);
                });
            },
            handleNodeClick(node) {
                if (node.id === -1) {
                    // 代码编辑器
                    this.showCodeEditor = true;
                    this.currentTitle = '代码编辑器';
                    this.currentMemo = {
                        id: -1,
                        parentId: null,
                        type: 1,
                        title: '代码编辑器',
                        context: '// 输入你的代码\nconsole.log("Hello, World!");'
                    };
                    this.navigateToEditor();
                } else if (node.type === 0) {
                    // 文件夹 - 展开/折叠
                    const index = this.expandedKeys.indexOf(node.id);
                    if (index > -1) {
                        this.expandedKeys.splice(index, 1);
                    } else {
                        this.expandedKeys.push(node.id);
                    }
                } else {
                    // 文本文件 - 打开编辑
                    this.showCodeEditor = false;
                    this.currentTitle = node.title;
                    this.getMemoInfo(node);
                    this.navigateToEditor();
                }
            },
            getMemoInfo(node) {
                if (node.id <= 0) return;

                axios.get('/memo/getInfo', {
                    headers: {
                        token: localStorage.getItem('token')
                    },
                    params: {
                        id: node.id
                    }
                }).then((response) => {
                    this.currentMemo = response.data.data;
                }).catch((error) => {
                    this.$message.error(error.message);
                });
            },
            saveMemo() {
                this.$loading();
                axios.post('/memo/save', {
                    id: this.currentMemo.id,
                    parentId: this.currentMemo.parentId,
                    type: this.currentMemo.type,
                    icon: this.currentMemo.icon,
                    sort: this.currentMemo.sort,
                    title: this.currentMemo.title,
                    context: this.currentMemo.context,
                }, {
                    headers: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    this.$loading().close();
                    this.$message.info('保存成功');
                    this.getTree();
                    this.getFolder();
                }).catch((error) => {
                    this.$loading().close();
                    this.$message.error(error.message);
                });
            },
            openFolderDrawer(node) {
                this.folderDrawer = true;
                this.currentFolder = {...node};
            },
            saveFolder() {
                axios.post('/memo/save', {
                    id: this.currentFolder.id,
                    parentId: this.currentFolder.parentId,
                    type: 0,
                    sort: this.currentFolder.sort,
                    title: this.currentFolder.title,
                    context: '',
                }, {
                    headers: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    this.$message.info('保存成功');
                    this.folderDrawer = false;
                    this.getTree();
                    this.getFolder();
                }).catch((error) => {
                    this.$message.error(error.message);
                });
            },
            insertMemo(parentId) {
                axios.post('/memo/save', {
                    parentId: parentId,
                    type: 1,
                    sort: 0,
                    title: "新建文本",
                    context: "",
                }, {
                    headers: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    this.$message.info('新增成功');
                    this.getTree();
                    this.getFolder();
                }).catch((error) => {
                    this.$message.error(error.message);
                });
            },
            deleteMemo(node) {
                this.$confirm('确认删除？', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    axios.delete('/memo/delete', {
                        headers: {
                            token: localStorage.getItem('token')
                        },
                        params: {
                            id: node.id
                        },
                    }).then((response) => {
                        this.$message.info('删除成功');
                        this.getTree();
                        this.getFolder();
                        if (this.currentMemo.id === node.id) {
                            this.goBack();
                        }
                    }).catch((error) => {
                        this.$message.error(error.message);
                    });
                }).catch(() => {});
            },
            run() {
                this.$loading();
                axios.post('/ide/run', {
                    lang: 'JavaScript',
                    input: '',
                    code: this.currentMemo.context,
                }, {
                    headers: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    this.$loading().close();
                    if(response.data.data === null) {
                        this.$message.error("代码运行失败，请重试");
                        return;
                    }
                    this.output = response.data.data.context;
                }).catch((error) => {
                    this.$loading().close();
                    this.$message.error(error.message);
                });
            },
            clearToken() {
                axios.get('/logout', {
                    params: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    this.localStorage.setItem('token', '');
                    window.location.href = '/login';
                }).catch((error) => {
                    this.$message.error(error.message);
                });
            },
            jump(url) {
                window.location.href = url;
                this.drawerVisible = false;
            },
        }
    };

    var Ctor = Vue.extend(Main);
    new Ctor().$mount('#app');
</script>
</body>
</html>